clear all
set more off

do "set_path.do"

***** Fig A1, A4: SDR volume *****

global sdrdir			"${datadir}sdr/"
global sdrout			"${outdir}figures/sdr/"

global cipdata			"${datadir}cip_all_both.dta"
global sdrdownload		"${sdrdir}sdr_combined_download.dta"
global sdrclean			"${sdrdir}sdr_combined_cleaned.dta"


*** I. Retrieve FX ***

use "$cipdata", clear

bys currency date: keep if _n==1
gen month = mofd(date)
format month %tm
bys currency month: egen avg_spot = mean(spot_norm)

keep currency month avg_spot
duplicates drop

save "${tempdir}fx_month_temp.dta", replace


*** II. Functions ***

capture program drop switchvar
program define switchvar
	gen _tempvar = `1' if `3'
	replace `1' = `2' if `3'
	replace `2' = _tempvar if `3'
	drop _tempvar
end

capture program drop switchvars
program define switchvars
	switchvar Leg1 Leg2 `1'
	switchvar Rate1 Rate2 `1'
	switchvar Not1 Not2 `1'
	switchvar Curr1 Curr2 `1'
	switchvar PF1 PF2 `1'
	switchvar RF1 RF2 `1'

	capture confirm variable Leg1Ref, exact
    if !_rc {
		switchvar Leg1Ref Leg2Ref `1'
	}
end

capture program drop switchCurrlabel
program define switchCurrlabel
	* Switch Curr label, if necessary
	levelsof `1', local(Curr_levels)
	foreach curr of local Curr_levels {
		gen _switch = ((Curr1!="`curr'") & (Curr2=="`curr'") & (strpos(Leg1,"`curr")>0)) | ///
			((Curr2!="`curr'") & (Curr1=="`curr'") & (strpos(Leg2,"`curr")>0))
		switchvar Curr1 Curr2 _switch
		switchvar Not1 Not2 _switch // [Check] Unclear if we need to do this
		drop _switch
	}

	* Fix Curr label, if necessary
	foreach curr of local Curr_levels {
		//replace Curr1 = "`curr'" if ((Curr1!="`curr'") & strpos(Leg1,"`curr'")>0)
		//replace Curr2 = "`curr'" if ((Curr2!="`curr'") & strpos(Leg2,"`curr'")>0)
		replace Curr1 = "`curr'" if ((Curr1!="`curr'") & inlist(substr(Leg1,4,1),"-",".","/","_") & strupper(substr(Leg1,1,3))=="`curr'")
		replace Curr2 = "`curr'" if ((Curr2!="`curr'") & inlist(substr(Leg2,4,1),"-",".","/","_") & strupper(substr(Leg2,1,3))=="`curr'")
	}
end

capture program drop adjustCurr
program define adjustCurr	
	gen _switch = (!inlist(Curr1,"`1'") & inlist(Curr2,"`1'") & inlist(strupper(Leg1),"`2'")) | ///
		(!inlist(Curr2,"`1'") & inlist(Curr1,"`1'") & inlist(strupper(Leg2),"`2'"))
	switchvar Curr1 Curr2 _switch
	switchvar Not1 Not2 _switch // [Check] Unclear if we need to do this
	drop _switch

	replace Curr1 = "`1'" if !inlist(Curr1,"`1'") & inlist(strupper(Leg1),"`2'")
	replace Curr2 = "`1'" if !inlist(Curr2,"`1'") & inlist(strupper(Leg2),"`2'")
end

capture program drop classifyCurr
program define classifyCurr
	replace `3' = "OTHER"
	replace `3' = "FIXED" if `2'=="FIXED"

	replace `3' = "IBOR" if (`1'=="USD") & (strpos(strupper(`2'),"LIBO")>0)
	replace `3' = "SOFR" if (`1'=="USD") & (strpos(strupper(`2'),"SOFR")>0)

	replace `3' = "IBOR" if (`1'=="AUD") & ((strpos(strupper(`2'),"BBR")>0) | (strpos(strupper(`2'),"BBS")>0))
	replace `3' = "SOFR" if (`1'=="AUD") & (strpos(strupper(`2'),"AONIA")>0)

	replace `3' = "IBOR" if (`1'=="CAD") & (strpos(strupper(`2'),"CDOR")>0)
	replace `3' = "SOFR" if (`1'=="CAD") & (strpos(strupper(`2'),"CORRA")>0)

	replace `3' = "IBOR" if (`1'=="CHF") & (strpos(strupper(`2'),"LIBO")>0)
	replace `3' = "SOFR" if (`1'=="CHF") & (strpos(strupper(`2'),"TOIS")>0)
	replace `3' = "SOFR" if (`1'=="CHF") & (strpos(strupper(`2'),"SARON")>0)

	replace `3' = "IBOR" if (`1'=="DKK") & (strpos(strupper(`2'),"IBOR")>0)

	replace `3' = "IBOR" if (`1'=="CHF") & (strpos(strupper(`2'),"LIBO")>0)
	replace `3' = "SOFR" if (`1'=="CHF") & (strpos(strupper(`2'),"TOIS")>0)

	replace `3' = "IBOR" if (`1'=="EUR") & ((strpos(strupper(`2'),"EURI")>0) | (strpos(strupper(`2'),"LIBO")>0))
	replace `3' = "SOFR" if (`1'=="EUR") & ((strpos(strupper(`2'),"ESTER")>0) | (strpos(strupper(`2'),"ESTR")>0) | ///
		(strpos(strupper(`2'),"EUROSTR")>0) | (strpos(strupper(`2'),"EONIA")>0) | (strpos(strupper(`2'),"EONA")>0))

	replace `3' = "IBOR" if (`1'=="GBP") & (strpos(strupper(`2'),"LIB")>0)
	replace `3' = "SOFR" if (`1'=="GBP") & ((strpos(strupper(`2'),"SONIA")>0) | (strpos(strupper(`2'),"SONA")>0))

	disp(1)

	replace `3' = "IBOR" if (`1'=="JPY") & (strpos(strupper(`2'),"IBO")>0)
	replace `3' = "SOFR" if (`1'=="JPY") & ((strpos(strupper(`2'),"TONA")>0) | (strpos(strupper(`2'),"OIS")>0)) // Not sure what CDFR is

	replace `3' = "IBOR" if (`1'=="NOK") & ((strpos(strupper(`2'),"NIBO")>0) | (strpos(strupper(`2'),"LI3M")>0))
	replace `3' = "SOFR" if (`1'=="NOK") & (strpos(strupper(`2'),"NOWA")>0)

	replace `3' = "IBOR" if (`1'=="NZD") & ((strpos(strupper(`2'),"BKBM")>0) | (strpos(strupper(`2'),"BBR")>0))
	replace `3' = "SOFR" if (`1'=="NZD") & (strpos(strupper(`2'),"IONA")>0)

	replace `3' = "IBOR" if (`1'=="SEK") & (strpos(strupper(`2'),"IBOR")>0)
	replace `3' = "SOFR" if (`1'=="SEK") & (strpos(strupper(`2'),"SIOR")>0)

	replace `3' = "IBOR" if (`1'=="BRL") & (strpos(strupper(`2'),"CDI")>0) & (strpos(strupper(`2'),"ON")==0) 
	replace `3' = "SOFR" if (`1'=="BRL") & (strpos(strupper(`2'),"CDI")>0) & (strpos(strupper(`2'),"ON")>=0)

	replace `3' = "IBOR" if inlist(`1',"CLP","CLF") & ((strpos(strupper(`2'),"TNA")>0) | (strpos(strupper(`2'),"CAMARA")>0) | ///
		(strpos(strupper(`2'),"TCIP")>0) | (strpos(strupper(`2'),"ICPROM")>0) | ///
		(strpos(strupper(`2'),"LIBOR")>0))
	replace `3' = "IBOR" if inlist(`1',"CLP","CLF") & ((strpos(strupper(`2'),"ICP")>0) | (strpos(strupper(`2'),"OIS")>0))
	*** Need to check the right SOFR rate for Chile ***

	replace `3' = "IBOR" if (`1'=="COP") & ((strpos(strupper(`2'),"IBR")>0) | (strpos(strupper(`2'),"INDICADOR BANCARIO DE REFERENCIA")>0) | ///
		(strpos(strupper(`2'),"COP.CO/COL03/COP01")>0))

	replace `3' = "IBOR" if (`1'=="HUF") & (strpos(strupper(`2'),"BOR")>0)							 
	replace `3' = "IBOR" if (`1'=="IDR") & (strpos(strupper(`2'),"IBOR")>0)
	replace `3' = "IBOR" if (`1'=="ILS") & (strpos(strupper(`2'),"BOR")>0)
	replace `3' = "IBOR" if (`1'=="INR") & ((strpos(strupper(`2'),"MIBOR")>0) | (strpos(strupper(`2'),"MIFOR")>0) | (strpos(strupper(`2'),"MIOIS")>0))
	replace `3' = "IBOR" if (`1'=="KRW") & (strpos(strupper(`2'),"CD")>0)
	replace `3' = "IBOR" if (`1'=="MXN") & (strpos(strupper(`2'),"TIIE")>0)
	replace `3' = "IBOR" if (`1'=="PLN") & (strpos(strupper(`2'),"WIBO")>0)

	replace `3' = "IBOR" if (`1'=="RUB") & (strpos(strupper(`2'),"MOSPRIME")>0)
	replace `3' = "SOFR" if (`1'=="RUB") & (strpos(strupper(`2'),"RUONIA")>0)

	replace `3' = "IBOR" if (`1'=="THB") & (strpos(strupper(`2'),"THBFIX")>0)
	replace `3' = "SOFR" if (`1'=="THB") & (strpos(strupper(`2'),"THOR")>0)

	replace `3' = "IBOR" if (`1'=="TRY") & (strpos(strupper(`2'),"IBOR")>0)
	replace `3' = "SOFR" if (`1'=="TRY") & (strpos(strupper(`2'),"TLREF")>0)

	replace `3' = "IBOR" if (`1'=="ZAR") & ((strpos(strupper(`2'),"JIBAR")>0) | (strpos(strupper(`2'),"BBA")>0))
end


*** III. Correct data labeling ***

use "${sdrdownload}", clear

switchCurrlabel Curr1
switchCurrlabel Curr2

* CLP/CLF
gen _switch = (!inlist(Curr1,"CLP","CLF") & inlist(Curr2,"CLP","CLF") & inlist(strupper(Leg1),"CL-CLICP-BLOOMBERG","CAMARA PROMEDIO INDEX")) | ///
	(!inlist(Curr2,"CLP","CLF") & inlist(Curr1,"CLP","CLF") & inlist(strupper(Leg2),"CL-CLICP-BLOOMBERG","CAMARA PROMEDIO INDEX"))
switchvar Curr1 Curr2 _switch
switchvar Not1 Not2 _switch // [Check] Unclear if we need to do this
drop _switch

replace Curr1 = "CLP" if !inlist(Curr1,"CLP","CLF") & inlist(strupper(Leg1),"CL-CLICP-BLOOMBERG","CAMARA PROMEDIO INDEX")
replace Curr2 = "CLP" if !inlist(Curr2,"CLP","CLF") & inlist(strupper(Leg2),"CL-CLICP-BLOOMBERG","CAMARA PROMEDIO INDEX")

* MXN
replace Leg1 = "MXTIIE-28D.MEX06" if Leg1=="MXTIIE_28D.MEX06"
replace Leg2 = "MXTIIE-28D.MEX06" if Leg2=="MXTIIE_28D.MEX06"
adjustCurr "MXN" "MXTIIE-28D.MEX06"

* BRL
adjustCurr "BRL" "BR4CDI-ON.ONCDI"


***** III. Classify benchmark rates *****

gen Leg1Ref = ""
classifyCurr Curr1 Leg1 Leg1Ref
replace Leg1Ref = "OTHER" if Leg1Ref==""

gen Leg2Ref = ""
classifyCurr Curr2 Leg2 Leg2Ref
replace Leg2Ref = "OTHER" if Leg2Ref==""

* Adjust date format
gen effective_date = date(Effective,"MDY")
gen expiration_date = date(Expiration,"MDY")

gen _trade_date = substr(TradeTime,1,10)
gen trade_date = date(_trade_date, "MDY")
drop _trade_date

format effective_date %td
format expiration_date %td
format trade_date %td

drop Effective Expiration TradeTime

order Type Code effective_date expiration_date trade_date

gen trade_year = year(trade_date)

* Merge with available FX
gen _switch = (Curr2=="USD") & (Curr1!="USD")
switchvars _switch
drop _switch

gen month = mofd(trade_date)
format month %tm
mmerge month Curr2 using "${tempdir}fx_month_temp.dta", type(n:1) unmatch(master) umatch(month currency)
drop _merge month
replace avg_spot = . if Curr1 != "USD"

gen checked = .

local currs AUD CAD CHF DKK EUR GBP JPY NOK NZD SEK BRL CLP CNY COP HUF IDR ILS INR KRW MXN MYR PEN PHP PLN RUB THB TRY ZAR
foreach curr of local currs {	
	* Keep currency of interest on one side (Curr1)
	gen _switch = (Curr2=="`curr'") & (Curr1!="`curr'")
	switchvars _switch

	* Identify transactions with wrong notional
	gen _fx = Not1/Not2
	bys Curr1 Curr2 trade_year: egen _fx_median = median(_fx)
	replace _fx_median = avg_spot if !missing(avg_spot) & Curr2=="USD"
	gen _error = (Curr2=="`curr'") & (_fx<_fx_median/2) | (_fx>_fx_median*2)

	* Swap notional Not1 and Not2, if needed
	gen _swap_Not = _error & !checked & (1/_fx>=_fx_median/2) & (1/_fx<=_fx_median*2)
	switchvar Not1 Not2 _swap_Not
	replace checked = 1 if _swap_Not

	bys Curr1 Curr2 trade_year T: egen _Not1_median = median(Not1)
	bys Curr1 Curr2 trade_year T: egen _Not2_median = median(Not2)

	* Keep Notional 1; replace Notional 2
	gen _keep_Not1 = _error & !checked & (missing(Not2) | (Not2==0) | (abs(Not1/_Not1_median - 1) < abs(Not2/_Not2_median-1)))
	replace Not2 = Not1/_fx_median if _keep_Not1
	replace checked = 1 if _keep_Not1

	* Keep Notional 2; replace Notional 1
	gen _keep_Not2 = _error & !checked & (missing(Not1) | (Not1==0)| (abs(Not1/_Not1_median - 1) > abs(Not2/_Not2_median-1)))
	replace Not1 = Not2*_fx_median if _keep_Not2
	replace checked = 1 if _keep_Not2

	* Winsorize Notional Amount Not1
	gen _ratio1 = Not1 / _Not1_median
	winsor2 _ratio1, suffix(_w) cut(0 95) by(Curr1 Curr2 trade_year T) 
	gen _winsor_Not = (Curr1=="`curr'") & (_ratio1 != _ratio1_w)	
	replace Not1 = _Not1_median * _ratio1_w if _winsor_Not
	replace Not2 = Not1/_fx_median if _winsor_Not
	replace checked = 1 if _keep_Not1

	drop _switch _fx _fx_median _error _swap_Not _keep_Not* _Not* _winsor_Not _ratio*
}

save "${sdrclean}", replace


*** IV. Plot Charts ***

use "${sdrclean}", clear

rename T Tenor
replace Tenor="NA"


gen month = mofd(trade_date)
format month %tmCCYY
set graphics off
local groups g10 eme
local gr g10
local currencies AUD CAD CHF DKK EUR GBP JPY NOK NZD SEK USD


foreach curr of local currencies {	
	* Keep currency of interest on one side (Curr1)
	gen _switch = (Curr2=="`curr'") & (Curr1!="`curr'")
	switchvars _switch
	drop _switch

	* Aggregate monthly notional; use Not1 to keep currency consistent
	bys Curr1 Tenor Leg1Ref month: egen Not1_m = total(Not1)
	bys Curr1 Tenor Leg2Ref month: egen Not2_m = total(Not1)
	replace Not1_m = Not1_m/1e9
	replace Not2_m = Not2_m/1e9

	* Separate total notional by rate type for plotting
	levelsof Leg1Ref
	foreach rate in `r(levels)' {
		local var1 = "Not1_m_`rate'"
		local var2 = "Not2_m_`rate'"

		bys Curr1 Tenor month: egen _temp1 = max(Not1_m) if Leg1Ref=="`rate'"
		bys Curr1 Tenor month: egen _temp2 = max(Not2_m) if Leg2Ref=="`rate'"

		bys Curr1 Tenor month: egen `var1' = max(_temp1)
		bys Curr1 Tenor month: egen `var2' = max(_temp2)

		replace `var1' = 0 if missing(`var1')
		replace `var2' = 0 if missing(`var2')

		drop _temp1 _temp2
	}

	egen Not1_m_M2 = rowtotal(Not1_m_IBOR Not1_m_SOFR), missing
	egen Not1_m_M3 = rowtotal(Not1_m_M2 Not1_m_FIXED), missing
	egen Not1_m_M4 = rowtotal(Not1_m_M3 Not1_m_OTHER), missing

	egen Not2_m_M2 = rowtotal(Not2_m_IBOR Not2_m_SOFR), missing
	egen Not2_m_M3 = rowtotal(Not2_m_M2 Not2_m_FIXED), missing
	egen Not2_m_M4 = rowtotal(Not2_m_M3 Not2_m_OTHER), missing

	twoway bar Not1_m_IBOR month if Curr1=="`curr'" || rbar Not1_m_IBOR Not1_m_M2 month if Curr1=="`curr'" || rbar Not1_m_M2 Not1_m_M3 month if Curr1=="`curr'" || rbar Not1_m_M3 Not1_m_M4 month if Curr1=="`curr'" , ///
		yti("Billion `curr'", size(vsmall)) xti("") xlabel(, labsize(vsmall)) tlab(2017m1(12)2024m1) ylabel(, labsize(vsmall)) yline(0,extend lp(solid)) subtitle(, size(small) ring(0) pos(1) nobexpand) ///
		legend(size(vsmall) cols(4) label(1 "IBOR") label(2 "SOFR") label(3 "Fixed") label(4 "Other")) name("`curr'_leg1", replace) ///
		title("XCCY Transanction Volume - `curr' Leg", size(small)) legend(position(6)) note("")
	graph export "${sdrout}vol_single_own_`gr'_`curr'.pdf", replace
	//by(tenor_order2, title("XCCY Transanction Volume - `curr' Leg", size(small)) legend(position(6)) note("") yrescale im(vsmall)) 

	twoway bar Not2_m_IBOR month if Curr1=="`curr'" || rbar Not2_m_IBOR Not2_m_M2 month if Curr1=="`curr'" || rbar Not2_m_M2 Not2_m_M3 month if Curr1=="`curr'" || rbar Not2_m_M3 Not2_m_M4 month if Curr1=="`curr'" , ///
		yti("Billion `curr'", size(vsmall)) xti("") xlabel(, labsize(vsmall)) tlab(2017m1(12)2024m1) ylabel(, labsize(vsmall)) yline(0,extend lp(solid)) subtitle(, size(small) ring(0) pos(1) nobexpand) ///
		legend(size(vsmall) cols(4) label(1 "IBOR") label(2 "SOFR")  label(3 "Fixed") label(4 "Other")) name("`curr'_leg2", replace) ///
		title("XCCY Transanction Volume - `curr' Counter Leg", size(small)) legend(position(6)) note("")
	graph export "${sdrout}vol_single_ctr_`gr'_`curr'.pdf", replace
	//by(tenor_order2, title("XCCY Transanction Volume - `curr' Counter Leg", size(small)) legend(position(6)) note("") yrescale im(vsmall)) 


	drop Not1_m* Not2_m*		
}

set graphics on

grc1leg AUD_leg1 CAD_leg1 CHF_leg1 DKK_leg1 EUR_leg1 GBP_leg1 JPY_leg1 NOK_leg1 NZD_leg1 SEK_leg1
graph export "${outdir}figures/vol_own_`gr'.pdf", replace
grc1leg AUD_leg2 CAD_leg2 CHF_leg2 DKK_leg2 EUR_leg2 GBP_leg2 JPY_leg2 NOK_leg2 NZD_leg2 SEK_leg2
graph export "${outdir}figures/vol_ctr_`gr'.pdf", replace
